#include "CustomGeometryItem.h"
#include <QSGGeometry>
#include <QSGGeometryNode>
#include <QSGFlatColorMaterial>
CustomGeometryItem::CustomGeometryItem(QQuickItem* parent)
    : QQuickItem(parent)
{
    setFlag(QQuickItem::ItemHasContents);
    connect(this, &CustomGeometryItem::p1Changed, this, [this]() { update(); });
    connect(this, &CustomGeometryItem::p2Changed, this, [this]() { update(); });
    connect(this, &CustomGeometryItem::p3Changed, this, [this]() { update(); });
    connect(this, &CustomGeometryItem::p4Changed, this, [this]() { update(); });
    connect(this, &CustomGeometryItem::segmentCountChanged, this, [this]() { update(); });
}

CustomGeometryItem::~CustomGeometryItem() { }

QSGNode* CustomGeometryItem::updatePaintNode(QSGNode* oldNode, UpdatePaintNodeData* data)
{
    (void)data;

    QSGGeometryNode* node = nullptr;
    QSGGeometry*     geometry = nullptr;
    if (!oldNode) {
        node = new QSGGeometryNode;

        geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), m_segmentCount);
        geometry->setLineWidth(1);
        geometry->setDrawingMode(QSGGeometry::DrawLineStrip);

        node->setGeometry(geometry);
        node->setFlag(QSGNode::OwnsGeometry);

        auto material = new QSGFlatColorMaterial ;
        material->setColor(QColor("orange"));
        node->setMaterial(material);
        node->setFlag(QSGNode::OwnsMaterial);
    }
    else
    {
        node = static_cast<QSGGeometryNode*>(oldNode);
        geometry = node->geometry();
        geometry->allocate(m_segmentCount);
    }
    auto itemSize = size();
    auto vertices = geometry->vertexDataAsPoint2D();
    for (int i = 0; i < m_segmentCount; ++i)
    {
        qreal t = i / qreal(m_segmentCount - 1);
        qreal invt = 1 - t;

        QPointF p = invt * invt * invt * m_p1 + 3 * invt * invt * t  * m_p2 + 3 * invt * t * t * m_p3 + t * t * t * m_p4;
        float x = itemSize.width() * p.x();
        float y = itemSize.height() * p.y();
        vertices[i].set(x, y);
    }
    node->markDirty(QSGNode::DirtyGeometry);
    return node;
}
